<template>
	<div id="sticky-box" :style="{ height: height + 'px', zIndex: zIndex }">
		<div
			:class="className"
			:style="{
				top: isSticky ? stickyTop + 'px' : '',
				zIndex: zIndex,
				position: position,
				width: width,
				height: height + 'px',
			}"
		>
			<slot>
				<div>sticky</div>
			</slot>
		</div>
	</div>
</template>

<script setup name="Sticky" lang="ts">
import { ref, onMounted, onBeforeUnmount, onActivated } from 'vue';
const props = defineProps({
	stickyTop: {
		type: Number,
		default: 0,
	},
	zIndex: {
		type: Number,
		default: 1,
	},
	className: {
		type: String,
		default: '',
	},
});

const active = ref(false);
const position = ref<'static' | 'fixed'>('static');
const width = ref<any>();
const height = ref<any>();
const isSticky = ref(false);
onMounted(() => {
	height.value = document.getElementById('sticky-box')!.clientHeight;
	window.addEventListener('scroll', handleScroll);
	window.addEventListener('resize', handleResize);
});
onActivated(() => {
	handleScroll();
});
onBeforeUnmount(() => {
	window.removeEventListener('scroll', handleScroll);
	window.removeEventListener('resize', handleResize);
});
function sticky() {
	if (active.value) {
		return;
	}
	position.value = 'fixed';
	active.value = true;
	width.value = width.value + 'px';
	isSticky.value = true;
}
function handleReset() {
	if (!active.value) {
		return;
	}
	reset();
}
function reset() {
	position.value = 'static';
	width.value = 'auto';
	active.value = false;
	isSticky.value = false;
}
function handleScroll() {
	//   const width = $el.getBoundingClientRect().width;
	const stickyBox = document.getElementById('sticky-box') as HTMLDivElement;
	const clientWidth = stickyBox.clientWidth;
	width.value = clientWidth || 'auto';
	const offsetTop = Number(stickyBox.style.top);
	if (offsetTop < props.stickyTop) {
		sticky();
		return;
	}
	handleReset();
}
function handleResize() {
	if (isSticky.value) {
		width.value = (document.getElementById('sticky-box') as HTMLDivElement).clientWidth + 'px';
	}
}
</script>
